x86: Prevent an infinite series of traps
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Thu, 24 May 2007 09:39:28 +0000 (10:39 +0100)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Thu, 24 May 2007 09:39:28 +0000 (10:39 +0100)
In some cases, we can end up in a vicious cycle of fatal_trap()s
within fatal_trap()s. Panic after a certain number of attempts.

Signed-off-by: Nils Nieuwejaar <nils.nieuwejaar@sun.com>
Use a per-cpu depth variable.

Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/traps.c

index 61160cb5040a1a94b0adf838ac2761377aceff86..fb454043ebc268f17898e671634669a5e9ef84b6 100644 (file)
@@ -345,16 +345,26 @@ char *trapstr(int trapnr)
  */
 asmlinkage void fatal_trap(int trapnr, struct cpu_user_regs *regs)
 {
-    watchdog_disable();
-    console_start_sync();
+    static DEFINE_PER_CPU(char, depth);
 
-    show_execution_state(regs);
-
-    if ( trapnr == TRAP_page_fault )
+    /*
+     * In some cases, we can end up in a vicious cycle of fatal_trap()s
+     * within fatal_trap()s. We give the problem a couple of iterations to
+     * bottom out, and then we just panic.
+     */
+    if ( ++this_cpu(depth) < 3 )
     {
-        unsigned long cr2 = read_cr2();
-        printk("Faulting linear address: %p\n", _p(cr2));
-        show_page_walk(cr2);
+        watchdog_disable();
+        console_start_sync();
+
+        show_execution_state(regs);
+
+        if ( trapnr == TRAP_page_fault )
+        {
+            unsigned long cr2 = read_cr2();
+            printk("Faulting linear address: %p\n", _p(cr2));
+            show_page_walk(cr2);
+        }
     }
 
     panic("FATAL TRAP: vector = %d (%s)\n"